/*
 * TMap Designer - A Thematic Map design software
 * Copyright (C) 2006 World Health Organization
 * http://www.who.int
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 */
package who.tmap.toolkit.impl;

import java.awt.Shape;
import java.awt.geom.Ellipse2D;
import java.awt.geom.GeneralPath;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;

import who.tmap.bo.cd.CDPointSymbols;
import who.tmap.bo.cd.CDShapes;

public class ShapeHelper {

	public static final boolean AUTO_CENTER =true;
	public static final boolean AS_SPECIFIED =!AUTO_CENTER;
	
	public Shape makeSymbol( Point2D pt, double width, int symbol, boolean autoCenter ) {
		Shape shape =null;
		int shapeId =-1;
		
		switch( symbol ) {
			case CDPointSymbols.CROSS:
				shapeId =CDShapes.CROSS;
				break;
				
			case CDPointSymbols.CIRCLE:
				shapeId =CDShapes.CIRCLE;
				break;	
				
			case CDPointSymbols.TRIANGLE:
				shapeId =CDShapes.TRIANGLE;
				break;
				
			case CDPointSymbols.SQUARE:
			default:
				shapeId =CDShapes.SQUARE;
				break;
		}		
		
		shape =makeShape( pt, width, width, shapeId, autoCenter );
		
		return shape;
	}
	
	public Shape makeShape( Point2D pt, double width, double height, int shapeId, boolean autoCenter ) {
		Shape shape =null;
		
		Point2D pt2 =null;
		if ( autoCenter == AUTO_CENTER ) {
			pt2 =new Point2D.Double( pt.getX() - width/2d, pt.getY() - height/2d );
		} else {
			pt2 =pt;
		}
		
		switch( shapeId ) {
			case CDShapes.CROSS:
				shape =makeCross( pt2, width, height );
				break;
				
			case CDShapes.CIRCLE:
				shape =makeEllipse( pt2, width, height );
				break;	
				
			case CDShapes.TRIANGLE:
				shape =makeTriangle( pt2, width, height );
				break;
				
			case CDShapes.SQUARE:
				shape =makeRectangle( pt2, width, height );
				break;				
		}
		
		return shape;
	}
	
	private Shape makeRectangle( Point2D pt, double width, double height ) {
		Shape shape =new Rectangle2D.Double( pt.getX(), pt.getY(), width, height );
		
		return shape;		
	}
	
	private Shape makeEllipse( Point2D pt, double width, double height ) {
		Shape shape =new Ellipse2D.Double( pt.getX(), pt.getY(), width, height );
		
		return shape;
	}
	
	private Shape makeTriangle( Point2D pt, double width, double height ) {

		float wSize =(float)(width/2.d);
		float hSize =(float)(height/2.d);	
		
		float minX, minY, maxX, maxY, centerX, centerY;
		
		minX =(float)pt.getX();
		minY =(float)pt.getY();
		maxX =(float)pt.getX() + (float)width;
		maxY =(float)pt.getY() + (float)height;
		
		centerX =minX + wSize;
		centerY =minY + hSize;
		
		GeneralPath path =new GeneralPath();
		path.moveTo( (float)(centerX - wSize), (float)(centerY + hSize) );
		path.lineTo( (float)centerX, (float)(centerY - hSize) );
		path.lineTo( (float)(centerX + wSize), (float)(centerY + hSize) );
		path.closePath();		
		
		return path;
	}
	
	private Shape makeCross( Point2D pt, double width, double height ) {
		float qwSize =(float)(width/4.d);
		float qhSize =(float)(height/4.d);	
		
		float minX, minY, maxX, maxY, centerX, centerY;
		
		minX =(float)pt.getX();
		minY =(float)pt.getY();
		maxX =(float)pt.getX() + (float)width;
		maxY =(float)pt.getY() + (float)height;
		
		centerX =minX + ( (float)width / 2.f );
		centerY =minY + ( (float)height / 2.f );
		
		GeneralPath path =new GeneralPath();
		path.moveTo( minX + qwSize, minY );
		path.lineTo( centerX, minY + qhSize );
		path.lineTo( centerX + qwSize, minY );
		
		path.lineTo( maxX, minY + qhSize );
		path.lineTo( centerX + qwSize, centerY );
		path.lineTo( maxX, centerY + qhSize );
		
		path.lineTo( centerX + qwSize, maxY );						
		path.lineTo( centerX, centerY + qhSize );
		path.lineTo( minX + qwSize, maxY );
		
		path.lineTo( minX, centerY + qhSize );
		path.lineTo( minX + qwSize, centerY );
		path.lineTo( minX, minY + qhSize );			
		
		path.closePath();	
		
		return path;
	}
}
